//
//  CmnFunc.m
//  CmnLib
//
//  Created by 21CN Vgo on 10-8-16.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "CmnFunc.h"
#import "GDataDefines.h"
#import "CmnMacro.h"
#import "RegexKitLite.h"
#import "Reachability.h"
#import <mach/mach_host.h>
#import <CommonCrypto/CommonDigest.h>
#include <sys/xattr.h>

@implementation CmnFunc

+ (NSString *)GetSettingPath
{
	NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString * settingpath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Setting"];
	[[NSFileManager defaultManager] createDirectoryAtPath:settingpath withIntermediateDirectories:NO attributes:nil error:nil];

	NSString * path = [NSString stringWithString:settingpath];
	
	return path;
}

+ (NSString *)GetPropertyFilePath;
{
	NSString * settingspath = [CmnFunc GetSettingPath];
	NSString * path = [NSString stringWithString:[settingspath stringByAppendingPathComponent:@"Property.xml"]];
	return path;
}

+ (BOOL)SaveProperty:(NSString *)value forKey:(NSString *)key
{
	if (value == nil)
	{
		[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
	}
	else
	{
		[[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
	}
	
	return [[NSUserDefaults standardUserDefaults] synchronize];
	
//	BOOL bRet = FALSE;
//	
//	NSString * xmlpath = [CmnFunc GetPropertyFilePath];
//	
//	GDataXMLDocument * document = nil;
//	GDataXMLElement * rootElement = nil;
//	
//	NSLog(@"SaveProperty", nil);
//	
//	NSError * error;
//	
//	if ([[NSFileManager defaultManager] fileExistsAtPath:xmlpath])
//	{
//		NSString * xmlText = [NSString stringWithContentsOfFile:xmlpath encoding:NSUTF8StringEncoding error:nil];
//		document = [[GDataXMLDocument alloc] initWithXMLString:xmlText options:0 error:&error];
//		rootElement = [document rootElement];
//	}
//	
//	if (rootElement == nil)
//	{
//		rootElement = [GDataXMLNode elementWithName:@"properties"];
//	}
//	
//	if (rootElement)
//	{
//		NSArray * propList = [rootElement nodesForXPath:[NSString stringWithFormat:@"//properties/%@", key] error:&error];
//		GDataXMLElement * propElement = nil;
//		if ([propList count] == 0)
//		{
//			propElement = [GDataXMLNode elementWithName:key stringValue:value];
//			[rootElement addChild:propElement];
//		}
//		else
//		{
//			propElement = [propList objectAtIndex:0];
//			[propElement setStringValue:value];
//		}
//	}
//	
//	if (document == nil)
//		document = [[GDataXMLDocument alloc] initWithRootElement:rootElement];
//	if (document)
//	{
//		NSData * xmlData = document.XMLData;
//		
//		bRet = [xmlData writeToFile:xmlpath atomically:YES];
//	}
//	
//	SAFE_RELEASE(document);
//	
//	return bRet;
}

+ (NSString*)GetPropertyWithKey:(NSString *)key
{
	NSString * value = [[NSUserDefaults standardUserDefaults] stringForKey:key];
	
	if (value == nil)
	{
		NSString * xmlpath = [CmnFunc GetPropertyFilePath];
		
		GDataXMLDocument * document = nil;
		GDataXMLElement * rootElement = nil;
		
		//NSLog(@"GetPropertyWithKey", nil);
		
		NSError * error;
		
		if ([[NSFileManager defaultManager] fileExistsAtPath:xmlpath])
		{
			NSString * xmlText = [NSString stringWithContentsOfFile:xmlpath encoding:NSUTF8StringEncoding error:nil];
			document = [[GDataXMLDocument alloc] initWithXMLString:xmlText options:0 error:&error];
			rootElement = [document rootElement];
		}
		
		if (rootElement)
		{
			NSArray * propList = [rootElement nodesForXPath:[NSString stringWithFormat:@"//properties/%@", key] error:&error];
			GDataXMLElement * propElement = nil;
			if ([propList count])
			{
				propElement = [propList objectAtIndex:0];
				value = [NSString stringWithString:[propElement stringValue]];
			}
		}
		
		SAFE_RELEASE(document);
	}
	
	return value;
}

+ (float)getTotalDiskSpaceInBytes
{   
	float space = 0.0f;   
	NSError *error = nil;   
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);   
	NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];   

	if (dictionary)
	{   
		NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];   
		space = [fileSystemSizeInBytes floatValue];   
	} else {   
		NSLog(@"Error Obtaining File System Info: Domain = %@, Code = %d", [error domain], [error code]);   
	}

	return space;
}

+ (float)getFreeDiskSpaceInBytes
{
	float space = 0.0f;   
	NSError *error = nil;   
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);   
	NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];   
	
	if (dictionary)
	{   
		NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemFreeSize];   
		space = [fileSystemSizeInBytes floatValue];   
	} else {   
		NSLog(@"Error Obtaining File System Info: Domain = %@, Code = %d", [error domain], [error code]);   
	}   
	
	return space;
}

+ (NSString*)getDocumentDirectory
{
	NSString* dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
	
	return dir;
}

+ (NSString*)getPrivateDocumentDirectory
{
	NSString* dir = [CmnFunc getLibraryDirectory];
	dir = [dir stringByAppendingPathComponent:@"Private Documents"];
	
	if (![[NSFileManager defaultManager] fileExistsAtPath:dir])
	{
		[[NSFileManager defaultManager] createDirectoryAtPath:dir
								  withIntermediateDirectories:YES
												   attributes:nil
														error:NULL];
	}
	
	return dir;
}

+ (NSString*)getLibraryDirectory
{
	NSString* dir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
	
	return dir;
}

+ (NSString*)getCachesDirectory
{
	NSString* dir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
	
	return dir;
}

+ (NSString*)URLEncode:(NSString*)origString
{
	NSString * encoded = (NSString *)
	CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
											(CFStringRef)origString,
											NULL,
											CFSTR("!*'();:@&=+$,/?%#[] "),
											kCFStringEncodingUTF8);
	[encoded autorelease];
	
	return encoded;
}

+ (NSString*)URLDecode:(NSString*)origString
{
	NSString * decoded = [origString stringByReplacingOccurrencesOfString:@"+"
															   withString:@" "
																  options:NSLiteralSearch
																	range:NSMakeRange(0, [origString length])];
	
	decoded = (NSString *)
	CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault,
											   (CFStringRef)decoded,
											   CFSTR(""),
											   kCFStringEncodingUTF8);
	[decoded autorelease];
	
	return decoded;
}

+ (BOOL)isEmail:(NSString *)email
{
	NSString * strEmailMatchstring=@"\\b([a-zA-Z0-9%_.+\\-]+)@([a-zA-Z0-9.\\-]+?\\.[a-zA-Z]{2,6})\\b";
	return [email isMatchedByRegex:strEmailMatchstring];
}

+ (BOOL)isPhoneNumber:(NSString *)phoneNumber
{
	NSString * strEmailMatchstring=@"((\\d{11})|^((\\d{7,8})|(\\d{4}|\\d{3})-(\\d{7,8})|(\\d{4}|\\d{3})-(\\d{7,8})-(\\d{4}|\\d{3}|\\d{2}|\\d{1})|(\\d{7,8})-(\\d{4}|\\d{3}|\\d{2}|\\d{1}))$)";
	return [phoneNumber isMatchedByRegex:strEmailMatchstring];
}

static NSString * g_CurrentConfig;

+ (void)setCurrentConfig:(NSString *)currentConfig
{
	SAFE_RELEASE(g_CurrentConfig);
	g_CurrentConfig = [currentConfig retain];
}

+ (NSDictionary *)getCurrentConfigDictionary
{
	return [[[NSBundle mainBundle] infoDictionary] objectForKey:g_CurrentConfig];
}

+ (NSDictionary *)urlQueryToDictionary:(NSString *)query
{
	NSMutableDictionary *nsDict = nil;
	
	NSArray * params = [query componentsSeparatedByString: @"&"];
	if ([params count])
	{
		nsDict = [NSMutableDictionary dictionary];
		for (NSString * param in params)
		{
			NSArray * vals = [param componentsSeparatedByString: @"="];
			[nsDict setValue:[vals objectAtIndex:1] forKey:[vals objectAtIndex:0]];
		}
	}
	
	return nsDict;
}

+ (BOOL)checkCanUseWifi
{
	BOOL isEnableWIFI = [[Reachability reachabilityForLocalWiFi] currentReachabilityStatus] == ReachableViaWiFi;
	return isEnableWIFI;
}

+ (BOOL)checkCanUseNetwork
{
	BOOL isEnableNetwork = [[Reachability reachabilityForInternetConnection] currentReachabilityStatus] != NotReachable;
	return isEnableNetwork;
}

+ (unsigned int)countCores
{
    host_basic_info_data_t hostInfo;
    mach_msg_type_number_t infoCount;
	
    infoCount = HOST_BASIC_INFO_COUNT;
    host_info(mach_host_self(), HOST_BASIC_INFO, 
              (host_info_t)&hostInfo, &infoCount);
	
    return (unsigned int)(hostInfo.max_cpus);
}

#define CHUNK_SIZE 32768

+ (NSString*)inputStreamMD5:(NSInputStream *)inputStream
{
	CC_MD5_CTX md5;
	
	CC_MD5_Init(&md5);
	
	BOOL done = NO;
	
	uint8_t buffer[CHUNK_SIZE];
	
	while(!done)
	{
		NSUInteger nRead = [inputStream read:buffer maxLength:CHUNK_SIZE];
		
		if (nRead > CHUNK_SIZE)
			return @"";
		
		if (nRead > 0)
			CC_MD5_Update(&md5, buffer, nRead);
		else
			done = YES;
	}
	unsigned char digest[CC_MD5_DIGEST_LENGTH];
	CC_MD5_Final(digest, &md5);
	NSString* s = [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
				   digest[0], digest[1], 
				   digest[2], digest[3],
				   digest[4], digest[5],
				   digest[6], digest[7],
				   digest[8], digest[9],
				   digest[10], digest[11],
				   digest[12], digest[13],
				   digest[14], digest[15]];
	return s;
}

+ (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL
{
    const char* filePath = [[URL path] fileSystemRepresentation];
    const char* attrName = "com.apple.MobileBackup";
    u_int8_t attrValue = 1;

    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);

    return result == 0;
}

@end
